package com.koron.order.schedule;

import com.koron.bean.app.AppBean;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.order.common.controller.OrderReassignController;
import com.koron.order.defect.controller.DefectController;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName OrderSchedule
 * @description
 * @Author zhouj
 * @Date 2022/3/2 10:08
 */
@Api(tags = "工单待处理的自动激活")
@RestController
@Slf4j
@RequestMapping("/orderSchedule/")
@EnableScheduling   // .开启定时任务
public class OrderSchedule {

    @Autowired
    DefectController defectController;

    @Autowired
    OrderReassignController orderReassignController;

    // 根据异步操作数设置线程
    private ExecutorService threadPool = Executors.newFixedThreadPool(3);

    //工单待处理的自动激活--多个水司依次执行
    //先拿到可用连接 遍历去执行多个库
    //@Scheduled(cron = "0 0 2 * * ?")
    @XxlJob("activePending")
    @ApiOperation(value = "自动激活待处理工单")
    @GetMapping("activePending")
    public void activePending() {

        log.info("自动激活待处理工单开始");
        HashMap<String, SqlSessionFactory> factoryMap = getActiveConn();

        //连接得有
        Assert.isTrue(MapUtils.isNotEmpty(factoryMap));

        Set<String> set = factoryMap.keySet();
        for (String key : set) {
            if (!key.equalsIgnoreCase("_default")) {
                //执行定时任务
                threadPool.submit(() -> {
                    defectController.activePendingAuto(key);
                });
            }
        }
        log.info("自动激活待处理工单结束");

    }

    //责任人未派工超过一周未派工,每隔七天发送一次通知(同一个工单多次转派以最后一次为准) 0 0/3 * * * ? 0 0 9 * * ?
    //@Scheduled(cron = "0 0 9 * * ?")
    @XxlJob("notifyDispatch")
    @ApiOperation(value = "每隔七天通知派工")
    @GetMapping("notifyDispatch")
    public void notifyDispatch() {

        log.info("通知责任人派工开始");
        HashMap<String, SqlSessionFactory> factoryMap = getActiveConn();
        //连接得有
        Assert.isTrue(MapUtils.isNotEmpty(factoryMap));

        Set<String> set = factoryMap.keySet();
        for (String key : set) {
            if (!key.equalsIgnoreCase("_default")) {
                //执行定时任务
                threadPool.submit(() -> {
                    if (Objects.isNull(ThreadLocalContext.getApp())) {
                        AppBean appBean = new AppBean();
                        ThreadLocalContext.setApp(appBean);
                    }
                    ThreadLocalContext.getApp().setMark(key);
                    orderReassignController.notifyDispatch(key);
                    //清除信息  防止污染
                    ThreadLocalContext.clear();
                });
            }
        }
        log.info("通知责任人派工结束");

    }

    //获取可用连接
    public HashMap<String, SqlSessionFactory> getActiveConn() {
        HashMap<String, SqlSessionFactory> factoryMap = new HashMap<>();
        Field factoryMapField = null;

        try {
            factoryMapField = SessionFactory.class.getDeclaredField("factoryMap");
            factoryMapField.setAccessible(true);
            factoryMap = (HashMap<String, SqlSessionFactory>) factoryMapField.get(factoryMapField.getType().getClass());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("获取可用数据源连接失败:{}", e.getMessage());
        }
        return factoryMap;

    }

}
